package casbinService

import (
	"errors"
	"github.com/Sir-yuChen/funAnalyse/global"
	"github.com/Sir-yuChen/funAnalyse/global/dept"
	"github.com/Sir-yuChen/funAnalyse/model"
	"github.com/Sir-yuChen/funAnalyse/model/common/ApiReturn"
	"github.com/Sir-yuChen/funAnalyse/model/request"
	"github.com/Sir-yuChen/funAnalyse/service/commonService"
	"github.com/Sir-yuChen/funAnalyse/utils"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type StockDeptService struct{}

func NewStockDeptService() *StockDeptService {
	return &StockDeptService{}
}

//GetStockDept 多条件查询
func (u *StockDeptService) GetStockDept(req *model.StockDeptModel) (a ApiReturn.ApiReturnCode) {
	var mo []model.StockDeptModel
	sql := ""
	obj := model.NewStockDeptModel()
	tableName := obj.TableName()
	sqlCondition := utils.ReflectHandleStuct(req)
	if sqlCondition != "" {
		sql = `select * from ` + tableName + ` where ` + sqlCondition
	} else {
		sql = `select * from ` + tableName + ` order by id desc  limit 100 `
	}
	err := global.GVA_DB.Raw(sql).Scan(&mo).Error
	if err != nil {
		global.GVA_LOG.Error("casbin Get异常", zap.Any("req", req), zap.Any("sql", sql), zap.Error(err))
		return ApiReturn.ErrSystem
	}
	s := ApiReturn.OK
	s.Data = mo
	return s
}

//InsertStockDept
func (u *StockDeptService) InsertStockDept(req *request.InsterDeptRequest, c *gin.Context) (a ApiReturn.ApiReturnCode) {
	a = checkParamsByType(req)
	if a.Code != ApiReturn.OK.Code {
		return a
	}
	//获取操作账户的详情
	user, err := commonService.GetUserInfoByToken(c)
	if err != nil {
		return ApiReturn.ErrSystem
	}
	req.CreateBy = user.CustomerName
	var total int64
	switch req.InsterType {
	case dept.DEPT_INSTER_TYPE_DEPT: //新增部门
		err = global.GVA_DB.Transaction(func(tx *gorm.DB) error {
			var role model.StockCasbinRoleModel
			if err := tx.Model(model.StockCasbinRoleModel{}).Where(" role_name = ? And status = ? ", "super", "Y").First(&role).Error; err != nil {
				global.GVA_LOG.Error("新增部门校验Super角色异常", zap.Any("CustomerId", user.CustomerId))
				return err
			}
			//只有超级管理员才可以新增部门 特殊处理
			tx.Model(model.StockCasbinRoleRelationUserModel{}).Where(" user_id = ? And role_id = ? And status = ? ", user.CustomerId, role.Id, "Y").Count(&total)
			if total <= 0 {
				return errors.New(ApiReturn.NoPermission.Msg)
			} else {
				total = 0
			}
			req.Type = 1
			//1. 新增部门
			tx.Model(model.StockDeptModel{}).Where("dept_name = ? or dept_mark = ?", req.DeptName, req.DeptMark).Count(&total)
			if total > 0 {
				return errors.New("部门名称/或唯一标识已存在")
			}
			if req.ParentId != 0 {
				var detp model.StockDeptModel
				err = tx.Model(model.StockDeptModel{}).Where("type = ? And  id = ?", 1, req.ParentId).First(&detp).Error
				if err != nil {
					global.GVA_LOG.Error("查所属父部门信息异常", zap.Any("request", req), zap.Error(err))
					return err
				}
				if detp == (model.StockDeptModel{}) {
					global.GVA_LOG.Error("未查询到所属父部门信息", zap.Any("request", req))
					return errors.New("未查询到所属父部门信息")
				}
				if detp.Status == "N" {
					global.GVA_LOG.Error("所属父部门已被禁用", zap.Any("request", req))
					return errors.New("所属父部门已被禁用")
				}
				req.DeptOrder = detp.DeptOrder + 1
			} else {
				req.DeptOrder = 1
			}
			if err = tx.Model(model.StockDeptModel{}).Create(&req.StockDeptModel).Error; err != nil {
				global.GVA_LOG.Error("新增部门异常", zap.Any("request", req), zap.Error(err))
				return err
			}
			return nil
		})
		if err != nil {
			a = ApiReturn.TxErrSystem
			a.Msg = err.Error()
			return a
		}
		break
	case dept.DEPT_INSTER_TYPE_STAFF: //新增部门和员工关系
		// 1. 校验员工是否已经有所属部门
		var m model.StockDeptModel
		err = global.GVA_DB.Model(model.StockDeptModel{}).Where(" type = ? AND dept_staff = ? And status = ? ", 2, req.DeptStaff, "Y").Find(&m).Error
		if err != nil {
			global.GVA_LOG.Error("校验用户是否已经有归属部门 异常", zap.Any("request", req), zap.Error(err))
			return ApiReturn.ErrSystem
		}
		if m != (model.StockDeptModel{}) {
			global.GVA_LOG.Error("当前账户已经存在归属部门", zap.Any("request", req))
			return ApiReturn.ExistingDepartment
		}
		//2. 校验部门是否正常存在
		if err = global.GVA_DB.Model(model.StockDeptModel{}).Where(" type = ? AND id = ? And status = ? ", 1, req.Id, "Y").Find(&m).Error; err != nil {
			global.GVA_LOG.Error("校验部门是否存在,状态是否正常 异常", zap.Any("request", req), zap.Error(err))
			return ApiReturn.ErrSystem
		}
		req.ParentId = int64(m.Id)
		req.DeptMark = m.DeptMark
		req.DeptName = m.DeptName
		req.Type = 2
		req.Id = 0 //ID使用完要清除避免影响新增
		if err = global.GVA_DB.Model(model.StockDeptModel{}).Create(&req.StockDeptModel).Error; err != nil {
			global.GVA_LOG.Error("建立账户和部门关系异常", zap.Any("request", req))
			return ApiReturn.ErrSystem
		}
		break
	default:
		global.GVA_LOG.Error("DEPT 未定义新增类型", zap.Any("request", req))
		return ApiReturn.ErrParam
	}
	return ApiReturn.OK
}

//UpdateStockDept 更新
func (u *StockDeptService) UpdateStockDept(req *model.StockDeptModel) (a ApiReturn.ApiReturnCode) {
	if req.Id == 0 {
		return ApiReturn.ErrParam
	}
	err := global.GVA_DB.Model(req).Updates(req).Error
	if err != nil {
		global.GVA_LOG.Error("casbin Update异常", zap.Any("req", req), zap.Error(err))
		return ApiReturn.ErrSystem
	}
	return ApiReturn.OK
}

//DelStockDept 根据ID删除
func (u *StockDeptService) DelStockDept(req *model.StockDeptModel) (a ApiReturn.ApiReturnCode) {
	if req.Id == 0 {
		return ApiReturn.ErrParam
	}
	err := global.GVA_DB.Model(req).Where("id = ?", req.Id).Delete(model.StockDeptModel{}).Error
	if err != nil {
		global.GVA_LOG.Error("casbin Del异常", zap.Any("req", req), zap.Error(err))
		return ApiReturn.ErrSystem
	}
	return ApiReturn.OK
}

//新增部门表 参数校验
func checkParamsByType(req *request.InsterDeptRequest) (a ApiReturn.ApiReturnCode) {
	switch req.InsterType {
	case dept.DEPT_INSTER_TYPE_DEPT: //新增部门
		if req.DeptName == "" || req.DeptMark == "" || req.DeptStaff != "" {
			global.GVA_LOG.Error("新增部门 部门名称/部门唯一标识不能为空 员工字段不能有参数", zap.Any("DeptName", req.DeptName),
				zap.Any("DeptMark", req.DeptMark), zap.Any("DeptStaff", req.DeptStaff))
			return ApiReturn.ErrParam
		}
		break
	case dept.DEPT_INSTER_TYPE_STAFF: //新增部门和员工关系
		if req.DeptStaff == "" || req.Id <= 0 {
			global.GVA_LOG.Error("新增部门与员工关系 员工/所属部门ID不能为空", zap.Any("DeptStaff", req.DeptStaff), zap.Any("id", req.Id))
			return ApiReturn.ErrParam
		}
		break
	default:
		global.GVA_LOG.Error("DEPT 未定义新增类型", zap.Any("request", req))
		return ApiReturn.ErrParam
	}
	return ApiReturn.OK
}
